#include "log.hpp"
#include "Inet_Addr.hpp"
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include <strings.h>
#include <functional>

using translate_t = std::function<std::string(const std::string&)>;

#define SOCKET_FD_DEFAULT -1

enum
{
    SOCKET_ERROR = 1,
    BIND_ERROR,
    RECV_ERROR,
    SEND_ERROR
};

class UDPEchoServer
{
public:
    UDPEchoServer(uint16_t port, translate_t t)
        : _socketFd(SOCKET_FD_DEFAULT), _port(port), _t(t)
    {
    }

    void ServerInit()
    {
        // 创建套接字
        _socketFd = socket(AF_INET, SOCK_DGRAM, 0);
        if (-1 == _socketFd)
        {
            LOG(FATA, "ServerInit socket() ERROR: errno %d: %s", errno, strerror(errno));
            exit(SOCKET_ERROR);
        }

        struct sockaddr_in addr;
        bzero(&addr, sizeof(addr));

        addr.sin_family = AF_INET;    // 16位地址类型
        addr.sin_port = htons(_port); // 16位端口号，主机序列转网络序列
        addr.sin_addr.s_addr = INADDR_ANY; // 任意IP

        // 绑定bind
        int ret = bind(_socketFd, (struct sockaddr *)&addr, sizeof(addr));
        if (-1 == ret)
        {
            LOG(FATA, "ServerInit bind() ERROR: errno %d: %s", errno, strerror(errno));
            exit(BIND_ERROR);
        }

        LOG(INFO, "ServerInit SUCCESS");
    }

    void ServerStart()
    {
        LOG(DEBUG, "ServerStart......");
        while (true)
        {
            // 用来记录信息发送方(client)的socket信息
            struct sockaddr_in client_addr;
            socklen_t client_addrLen = sizeof(client_addr);
            bzero(&client_addr, sizeof(client_addr));

            // 接收信息
            char buffer[1024] = {0};
            int ret = recvfrom(_socketFd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&client_addr, &client_addrLen);
            if (-1 == ret)
            {
                LOG(FATA, "Server recvfrom() ERROR: errno %d: %s", errno, strerror(errno));
                exit(RECV_ERROR);
            }
            if (ret > 0)
            {
                // 解析发送方（client）的socket信息
                InetAddr addr(client_addr);
                LOG(INFO, "Server receve# %s from [%s:%d]", buffer, addr.IP().c_str(), addr.Port());

                //执行翻译
                std::string english(buffer);
                std::string chinese = _t(english);

                // 发送信息
                ret = sendto(_socketFd, chinese.c_str(), chinese.size(), 0, (struct sockaddr *)&client_addr, client_addrLen);
                if (-1 == ret)
                {
                    LOG(FATA, "Server sendto() ERROR: errno %d: %s", errno, strerror(errno));
                    exit(SEND_ERROR);
                }

                // // 发送信息
                // ret = sendto(_socketFd, buffer, strlen(buffer), 0, (struct sockaddr *)&client_addr, client_addrLen);
                // if (-1 == ret)
                // {
                //     LOG(FATA, "Server sendto() ERROR: errno %d: %s", errno, strerror(errno));
                //     exit(SEND_ERROR);
                // }
            }
            
        }
    }

private:
    int _socketFd;
    uint16_t _port;
    translate_t _t;
};